﻿using KingerRobot.MexicoSailunMDC.Dao;
using KingerRobot.MexicoSailunWMS.Spi;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KingerRobot.MexicoSailunWMS.SpiService
{
    public class BScannerManageService : IScannerManage
    {
        private readonly static IWcsScanner _WcsScanner = new BWcsScanner();
        private readonly static IRcsLocation _RcsLocation = new BRcsLocation();
        #region 扫描成功率
        public List<ScannerSuccessRateBeans> GetScannerSuccessRate(ScannerSuccessRateCondition condition)
        {


            #region 获取数据



            var startTime = (condition.TimeSlot is null || condition.TimeSlot.Count() < 2 || String.IsNullOrWhiteSpace(condition.TimeSlot[0])) ? DateTime.Now.AddDays(-1) : GetDate(condition.TimeSlot[0]);
            var endTime = (condition.TimeSlot is null || condition.TimeSlot.Count() < 2 || String.IsNullOrWhiteSpace(condition.TimeSlot[1])) ? DateTime.Now : GetDate(condition.TimeSlot[1]);


            //var bakWcsTaskCmdSlotResult = Task.Run(() =>
            //{
            //    var db = Db.Default;
            //    {
            //        var data = db.BakWcsTaskCmds.Where(f => f.CreateTime >= startTime && f.CreateTime <= endTime).Select(f => new
            //        {
            //            f.CreateTime,
            //            f.EquipId,
            //            f.CmdType,
            //            f.TaskId
            //        }).ToList();
            //        data = data
            //            .Where(f => f.CmdType == (int)EnumTaskType.Warehousing ||
            //            f.CmdType == (int)EnumTaskType.Transportation ||
            //            f.CmdType == (int)EnumTaskType.Abnormal).ToList();
            //        return data;
            //    }

            //});

            //var bakWcsTaskSlotResult = Task.Run(() =>
            //{
            //    var db = Db.Default;
            //    {
            //        var data = db.BakWcsTasks.Where(f => f.CreateTime >= startTime && f.CreateTime <= endTime).ToList();
            //        data = data.Where(f => f.TaskType == (int)EnumTaskType.Warehousing ||
            //    f.TaskType == (int)EnumTaskType.Transportation ||
            //    f.TaskType == (int)EnumTaskType.Abnormal).ToList();
            //        return data;
            //    }
            //});

            //var db = Db.Default;
            //var rcsEquip = db.RcsEquips.AsEnumerable().ToList();

            //var bakWcsTaskCmdSlot = bakWcsTaskCmdSlotResult.Result;

            //var cmdQuery = rcsEquip.Join(bakWcsTaskCmdSlot, f => f.Id, s => s.EquipId, (f, s) => new
            //{
            //    ScannerName = f.EquipName,
            //    EquipType = f.EquipType,
            //    CmdType = s.CmdType,
            //    Cmd = s
            //}).ToList();

            //var bakWcsTaskSlot = bakWcsTaskSlotResult.Result;
            //var taskQuery = cmdQuery.Join(bakWcsTaskSlot, f => f.Cmd.TaskId, s => s.Id, (f, s) => new
            //{
            //    ScannerName = f.ScannerName,
            //    EquipType = f.EquipType,
            //    CmdType = f.CmdType,
            //    Task = s
            //}).ToList();

            //var query = taskQuery.Join(db.ProdSkuProducts, f => f.Task.SkuId, s => s.SkuId, (f, s) => new
            //{
            //    ScannerName = f.ScannerName,
            //    EquipType = f.EquipType,
            //    CmdType = f.CmdType,
            //    Skuproduct = s,
            //    RemarkMemo = f.Task.RemarkMemo,
            //})
            // .Join(db.ProdProducts, f => f.Skuproduct.ProductId, s => s.Id, (f, s) => new
            // {
            //     ScannerName = f.ScannerName,
            //     EquipType = f.EquipType,
            //     CmdType = f.CmdType,
            //     ProductCode = s.ProductCode,
            //     RemarkMemo = f.RemarkMemo
            // })
            // .Where(f => f.EquipType == 1 || f.EquipType == 8)//筛选出入库扫描和旋转角度扫描
            // .ToList();



            var scannerRecords = _WcsScanner.GetWcsScannerListByDate(startTime, endTime);

            var scanners = _RcsLocation.GetLocationByType((int)EnumLocType.Scanner);

            var query = scannerRecords.Join(scanners, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.StartLoc,
                s.LocName
            }).ToList();


            var faileResult = query //获取没有扫到条码的数量
                .Where(f => f.Barcode.Contains(ConstFields.NoRead))//筛选出未扫到条码的任务
                .GroupBy(f => new { f.LocName })
                .Select(f => new
                {
                    ScannerName = f.Key.LocName,
                    FaileCount = f.Count(),
                }).ToList();


            var result = query  //获取所有扫描设备扫描的总数
                .GroupBy(f => new { f.LocName })
                .Select(f => new
                {
                    ScannerName = f.Key.LocName,
                    TotalCount = f.Count(),
                })
                .GroupJoin(faileResult, f => f.ScannerName, s => s.ScannerName, (f, s) => new
                {
                    ScannerName = f.ScannerName,
                    TotalCount = f.TotalCount,
                    Fr = s
                })
                .SelectMany(t => t.Fr.DefaultIfEmpty(), (f, s) => new
                {
                    ScannerName = f.ScannerName,
                    TotalCount = f.TotalCount,
                    FaileCount = s == null ? 0 : s.FaileCount
                })
            .OrderByDescending(f => f.FaileCount)
            .ToList();



            #endregion


            //if (!String.IsNullOrWhiteSpace(condition.ScannerName))//指定扫描仪
            //{
            //    result = result.Where(f => f.ScannerName.Contains(condition.ScannerName)).ToList();
            //}

            //var scannerList = _WcsScanner.GetWcsScannerListByDate(startTime, endTime);



            return result.Select(f => new ScannerSuccessRateBeans
            {
                ScannerName = f.ScannerName,
                TotalNum = f.TotalCount,
                FaileNum = f.FaileCount,
                SuccessRate = GetRate(f.TotalCount, f.FaileCount)
            }).ToList();
        }

        ///计算成功比例
        public string GetRate(int totalCount, int faileCount)
        {
            double faileNum = (double)faileCount;
            double totalNum = (double)totalCount;


            double d = (totalNum - faileNum) / totalNum;
            //double d = (totalNum - faileNum) / totalNum * 100;

            // decimal rate = decimal.Round(decimal.Parse(d+""), 2);

            return d.ToString("P2");//rate + "%";
        }

        public DateTime GetDate(String dateStr)
        {
            /*            DateTime date = DateTime.ParseExact(dateStr, "MM/dd/yyyy HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture);

                       string dateStr2 = date.ToString("yyyy-MM-dd HH:mm:ss");*/

            return DateTime.ParseExact(dateStr.Trim(), "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture);
        }

        #endregion


        #region 入库扫描异常
        public List<ScannerExceptionBeans> GetScannerException(ScannerExceptionCondition condition)
        {
            var db = Db.Default;
            var result = db.BakWcsTaskCmds.Join(db.RcsEquipScanners, f => f.EquipId, s => s.Id, (f, s) => new
            {
                ScannerTime = f.CreateTime,
                TaskNo = f.TaskNo,
                TaskCmd = f
            })
            .Where(f => f.TaskCmd.CmdType == (int)EnumTaskType.Abnormal)//异常任务
            .Join(db.RcsEquips, f => f.TaskCmd.EquipId, s => s.Id, (f, s) => new
            {
                ScannerTime = f.ScannerTime,
                TaskNo = f.TaskNo,
                ScannerEquip = s.EquipName,
                TaskCmd = f.TaskCmd
            })
            .Join(db.BakWcsTasks, f => f.TaskCmd.TaskId, s => s.Id, (f, s) => new
            {
                ScannerTime = f.ScannerTime,
                TaskNo = f.TaskNo,
                ScannerEquip = f.ScannerEquip,
                ExceptionContent = s.RemarkMemo,
                Task = s
            })
            .Join(db.ProdSkuProducts, f => f.Task.SkuId, s => s.SkuId, (f, s) => new
            {
                ScannerTime = f.ScannerTime,
                TaskNo = f.TaskNo,
                ScannerEquip = f.ScannerEquip,
                ExceptionContent = f.ExceptionContent,
                SkuProduct = s
            })
            .Join(db.ProdProducts, f => f.SkuProduct.ProductId, s => s.Id, (f, s) => new
            {
                ScannerTime = f.ScannerTime,
                TaskNo = f.TaskNo,
                ScannerEquip = f.ScannerEquip,
                ExceptionContent = f.ExceptionContent,
                ProductCode = s.ProductCode,
                Product = s
            })
            .Join(db.ProdMaterials, f => f.Product.MaterialId, s => s.Id, (f, s) => new
            {
                ScannerTime = f.ScannerTime,
                TaskNo = f.TaskNo,
                ScannerEquip = f.ScannerEquip,
                ExceptionContent = f.ExceptionContent,
                ProductCode = f.ProductCode,
                Spec = s.Spec
            })
            .OrderByDescending(f => f.ScannerTime)
            .ToList();

            //指定时间段
            if ((condition.StartTime is not null && condition.StartTime != DateTime.MinValue) && (condition.EndTime is not null && condition.EndTime != DateTime.MinValue))
            {
                result = result.Where(f => f.ScannerTime >= condition.StartTime && f.ScannerTime <= condition.EndTime).ToList();
            }

            if (!String.IsNullOrWhiteSpace(condition.ProductCode))//指定条码
            {
                result = result.Where(f => f.ProductCode.Contains(condition.ProductCode)).ToList();
            }

            return result.Select(f => new ScannerExceptionBeans
            {
                ProductCode = f.ProductCode,
                Spec = f.Spec,
                TaskNo = f.TaskNo,
                ScannerEquip = f.ScannerEquip,
                ScannerTime = f.ScannerTime,
                ExceptionContent = f.ExceptionContent
            }).ToList();

        }

        #endregion



        public List<HourScannerCount> GetHourScannerCountByDate(string date)
        {
            var result = _WcsScanner.GetHourScannerCountByDateV2(date);
            return result;
        }

        public List<HourScannerCount> GetMinScannerCountByDate(string date)
        {
            var result = _WcsScanner.GetMinScannerCountByDateV2(date);
            return result;
        }


        public List<OutScannerAfterBean> GetWcsOutScannerAfter(OutScannerAfterBeanParam param)
        {
            var result = _WcsScanner.GetWcsOutScannerAfter(param.StartTime, param.EndTime);
            return result;
        }

        public List<ProductScannerRecord> GetProductScannerRecordByCode(string ProductCode)
        {
            var result = _WcsScanner.GetProductScannerRecordByCode(ProductCode);
            return result;
        }

        public List<ScannerErrorList> GetErrorScanner()
        {
            var db = Db.Default;
            var result = db.WcsScanners.Join(db.WcsScannerErrorList, f => f.ErrorCode, s => s.ErrorCode, (f, s) => new
            {
                WcsScanners = f,
                WcsScannerErrorList = s,
            }).Where(t => t.WcsScanners.UseFlag == 1 && t.WcsScanners.TaskId == 0 && t.WcsScanners.ErrorCode != 0)
            .Join(db.RcsLocations, f => f.WcsScanners.StartLoc, s => s.Id, (f, s) => new ScannerErrorList
            {
                CreateTime = f.WcsScanners.CreateTime,
                ErrorCode = f.WcsScanners.ErrorCode,
                ErrorName = f.WcsScannerErrorList.ErrorName,
                Remark = f.WcsScannerErrorList.RemarkMemo,
                ScannerId = f.WcsScanners.Id,
                ScannerName = s.LocName,
                barCode = f.WcsScanners.Barcode,
            }).ToList();
            return result;
        }
    }
}
